package com.dlc.hardwareprotocol.serialport.command.send;

import android.os.SystemClock;


import com.dlc.hardwareprotocol.Protocol;
import com.dlc.hardwareprotocol.serialport.command.SendCommand;
import com.dlc.hardwareprotocol.serialport.utils.ByteUtil;
import com.dlc.hardwareprotocol.serialport.utils.LogPlus;

import java.nio.ByteBuffer;


abstract class SendBase implements SendCommand {

    private byte[] mBytes;
    private int cmd;
    private long mSendTime;

    protected byte targetAddress = 0x01;


    public SendBase(int cmd) {
        this.cmd = cmd;
    }

    public int getCmd() {
        return cmd;
    }

    /**
     * Command Data 是命令帧中的参数域, 即协议中的Command Data
     *
     * @return
     */
    protected abstract byte[] getCommandDataN();

    public synchronized byte[] toBytes() {
        byte[] bytes = mBytes;

        if (bytes == null) {
            byte[] dataN = getCommandDataN();
            if (dataN == null) {
                dataN = new byte[0];
            }

            int packLen = Protocol.MIN_PACK_LEN + dataN.length;//1字节，包括命令码、协议版本和数据域的长度
            bytes = new byte[packLen];

            ByteBuffer byteBuffer = ByteBuffer.wrap(bytes);
            byteBuffer.clear();
            // 帧头
            byteBuffer.put(Protocol.FRAME_HEAD);
            // 源地址
            byteBuffer.put((byte) 0x00);
            // 目标地址
            byteBuffer.put(targetAddress);
            // 数据长度 //1字节，包括命令码、协议版本和数据域的长度
            byte[] dataLengthBytes = ByteUtil.int2Bytes(dataN.length + 1 + 1, 1);
            byteBuffer.put(dataLengthBytes);
            // 命令码
            byteBuffer.put((byte) cmd);
            // 协议版本
            byteBuffer.put((byte) 0x10);
            // 数据
            byteBuffer.put(dataN);
            // 异或校验
            byteBuffer.put(ByteUtil.getXOR(bytes, 0, bytes.length - 1));
            mBytes = bytes;
        }
        LogPlus.e("send bytes: hex:" + ByteUtil.bytes2HexStr(mBytes));
        return mBytes;
    }

    @Override
    public long getSendTime() {
        return mSendTime;
    }

    @Override
    public void updateSendTime() {
        mSendTime = SystemClock.elapsedRealtime();
    }

    public void setTargetAddress(byte targetAddress) {
        this.targetAddress = targetAddress;
    }
}